﻿#include "yaml.hpp"
#include <cstdio>
#include <fstream>
#include <list>
#include <memory>
#include <sstream>
#include <stdarg.h>
#include <vector>

#ifdef _WIN32
#include <windows.h>
#else
#include <errno.h>
#include <sys/stat.h>
#endif

namespace cppc {
namespace yaml {
class ReaderLine;

static const std::string g_trimmed_chars = "\a\b\t\r\n\v\f ";
// 异常信息定义
static const std::string g_errorInvalidCharacter = "发现无效字符";
static const std::string g_errorKeyMissing = "缺少KEY";
static const std::string g_errorKeyIncorrect = "KEY不正确";
static const std::string g_errorValueIncorrect = "值不正确";
static const std::string g_errorTabInOffset = "缩进中发现TAB制表符";
static const std::string g_errorBlockSequenceNotAllowed = "在此上下文中不允许有序列条目";
static const std::string g_errorUnexpectedDocumentEnd = "文档意外结束";
static const std::string g_errorDiffEntryNotAllowed = "上下文中不允许有不同类型的项目";
static const std::string g_errorIncorrectOffset = "不正确的缩进";
static const std::string g_errorSequenceError = "序列节点中的错误";
static const std::string g_errorCannotOpenFile = "无法打开文件";
static const std::string g_errorIndentation = "空格缩进少于2";
static const std::string g_errorInvalidBlockScalar = "无效的块标量";
static const std::string g_errorInvalidQuote = "无效的引号";
static const std::string g_errorInvalidFlowScalar = "无效的流标量";
static const std::string g_errorDirectoryCreate = "父目录不存在且创建失败";
static const std::string g_EmptyString = ""; ///< 空字符串
static yaml::YamlNode g_NoneNode;            ///< 空节点

// 格式化异常信息
static std::string ExceptionMessage(const std::string &message, ReaderLine &line);
static std::string ExceptionMessage(const std::string &message, ReaderLine &line, const size_t errorPos);
static std::string ExceptionMessage(const std::string &message, const size_t errorLine, const size_t errorPos);
static std::string ExceptionMessage(const std::string &message, const size_t errorLine, const std::string &data);

std::string LeftTrim(const std::string &str) {
    std::string trimmedStr = str;
    trimmedStr.erase(0, trimmedStr.find_first_not_of(g_trimmed_chars));
    return trimmedStr;
}

std::string RightTrim(const std::string &str) {
    std::string trimmedStr = str;
    trimmedStr.erase(trimmedStr.find_last_not_of(g_trimmed_chars) + 1);
    return trimmedStr;
}

std::string Trim(const std::string &str) {
    std::string trimmedStr = str;
    trimmedStr.erase(0, trimmedStr.find_first_not_of(g_trimmed_chars));
    trimmedStr.erase(trimmedStr.find_last_not_of(g_trimmed_chars) + 1);
    return trimmedStr;
}

std::vector<std::string> SplitStr(const std::string &str, const char delimiter) {
    std::vector<std::string> result;
    std::string token;
    std::istringstream stream(str);

    while (std::getline(stream, token, delimiter)) {
        result.push_back(token);
    }
    return result;
}

std::string RemoveTrailingZeros(const std::string &str) {
    std::regex pattern(R"((\.\d*[1-9])0+$|\.0+$)");
    std::string result = std::regex_replace(str, pattern, "$1");
    if (!result.empty() && result.back() == '.') {
        result.push_back('0');
    }
    return result;
}

bool IsValidNumeric(const std::string &str) {
    if (str.empty()) {
        return true;
    }
    std::regex pattern(R"(^[-+]?(\d+)(\.\d+)?$)");
    return std::regex_match(str, pattern);
}

bool CreateDirectoryx(const std::string &path, int mode) {
    std::string currentPath;
    std::string delimiter = "/";

#ifdef _WIN32
    delimiter = "\\";
#endif

    if (path.empty()) {
        return false;
    }
    struct stat st;
    if (stat(path.c_str(), &st) == 0) {
        return true;
    }

    size_t pos = 0;
    do {
        pos = path.find(delimiter, pos + 1);
        currentPath = path.substr(0, pos);
#ifdef _WIN32
        if (GetFileAttributesA(currentPath.c_str()) == INVALID_FILE_ATTRIBUTES) {
            if (!CreateDirectoryA(currentPath.c_str(), NULL)) { // 使用CreateDirectoryA
                std::cerr << "Error creating directory: " << currentPath << std::endl;
                return false;
            }
        }
#else
        if (mkdir(currentPath.c_str(), mode) != 0 && errno != EEXIST) {
            std::cerr << "Error creating directory: " << currentPath << std::endl;
            return false;
        }
#endif
    } while (pos != std::string::npos);

    return true;
}

std::string GetDirectoryFromFilePath(const std::string &filePath) {
    std::size_t found = filePath.find_last_of("/\\");

    if (found != std::string::npos) {
        return filePath.substr(0, found);
    }
    return ".";
}

/// 查找一对匹配的引号（双引号"或单引号'），并返回引号的起始和结束位置
/// \param input 待搜索字符串
/// \param start[int,out] 引号开始位置，如果找到则被赋值
/// \param end[int,out] 引号结束位置，如果找到则被赋值
/// \param searchPos[in] 搜索起始位置
/// \return 是否找到匹配的引号
static bool FindQuote(const std::string &input, size_t &start, size_t &end, size_t searchPos = 0) {
    start = end = std::string::npos;
    size_t qPos = searchPos;
    bool foundStart = false;

    while (qPos != std::string::npos) {
        // 找第一个引号
        qPos = input.find_first_of("\"'", qPos);
        if (qPos == std::string::npos) {
            return false;
        }

        const char token = input[qPos];
        if (token == '"' && (qPos == 0 || input[qPos - 1] != '\\')) {
            if (foundStart == false) { // 找到开始的引号
                start = qPos;
                foundStart = true;
            } else { // 找到结束的闭合引号
                end = qPos;
                return true;
            }
        }

        // 检查是否有可能进行另一个循环
        if (qPos + 1 == input.size()) {
            return false;
        }
        qPos++;
    }
    return false;
}

/// 查找在所有引号之外的第一个token字符的位置，并计算在该位置之前遇到的引号对的个数
/// \param input 待搜索字符串
/// \param token 特定字符token
/// \param preQuoteCount[out] 在找到的字符位置之前遇到的引号对数量。
/// \return 引号之外的第一个token字符的位置
static size_t FindNotCited(const std::string &input, char token, size_t &preQuoteCount) {
    preQuoteCount = 0;
    size_t tokenPos = input.find_first_of(token);
    if (tokenPos == std::string::npos) {
        return std::string::npos;
    }

    std::vector<std::pair<size_t, size_t>> quotes; // 找到所有的引号对
    size_t quoteStart = 0;
    size_t quoteEnd = 0;
    while (FindQuote(input, quoteStart, quoteEnd, quoteEnd)) {
        quotes.push_back({quoteStart, quoteEnd});
        if (quoteEnd + 1 == input.size()) {
            break;
        }
        quoteEnd++;
    }
    if (quotes.size() == 0) {
        return tokenPos;
    }

    size_t currentQuoteIndex = 0;
    std::pair<size_t, size_t> currentQuote = {0, 0};

    while (currentQuoteIndex < quotes.size()) {
        currentQuote = quotes[currentQuoteIndex];

        if (tokenPos < currentQuote.first) {
            return tokenPos;
        }
        preQuoteCount++;
        if (tokenPos <= currentQuote.second) {
            // 特殊字符在绰号内，接着找下一个特殊字符
            if (tokenPos + 1 == input.size()) {
                return std::string::npos;
            }
            tokenPos = input.find_first_of(token, tokenPos + 1);
            if (tokenPos == std::string::npos) {
                return std::string::npos;
            }
        }
        currentQuoteIndex++;
    }
    return tokenPos;
}

/// 查找在所有引号之外的第一个特定字符token的位置，并计算在该位置之前遇到的引号对的个数
/// \param input 待搜索字符串
/// \param token 特定字符token
/// \return 引号之外的第一个特定字符token的位置
static size_t FindNotCited(const std::string &input, char token) {
    size_t dummy = 0;
    return FindNotCited(input, token, dummy);
}

/// 确保字符串中的引号是否成对出现或者没有，并且没有被单独遗留在字符串末尾
static bool ValidateQuote(const std::string &input) {
    if (input.size() == 0) {
        return true;
    }

    char token = 0;
    size_t searchPos = 0;
    if (input[0] == '\"' || input[0] == '\'') {
        if (input.size() == 1) {
            return false;
        }
        token = input[0];
        searchPos = 1;
    }

    while (searchPos != std::string::npos && searchPos < input.size() - 1) {
        searchPos = input.find_first_of("\"'", searchPos + 1);
        if (searchPos == std::string::npos) {
            break;
        }

        const char foundToken = input[searchPos];
        if (input[searchPos] == '\"' || input[searchPos] == '\'') {
            if (token == 0 && input[searchPos - 1] != '\\') {
                return false; // 首字符不是引号，引号又不是转义。即双头不是引号包裹
            }
            if (foundToken == token && input[searchPos - 1] != '\\') {
                if (searchPos == input.size() - 1) {
                    return true; // 如果引号是最后一个，并且闭合了
                }
                return false;
            }
        }
    }
    return token == 0; // 没有引号是对的
}

/// 是否有效的key、value，是否符合YAML语法
static bool ShouldBeCited(const std::string &key) {
    return key.find_first_of("\":{}[],&*#?|-<>=!%@") != std::string::npos;
}

/// 输出时将转义字符转为文本
static std::string AddEscapeTokens(const std::string &value) {
    std::string escapeValue;
    static std::map<char, std::string> escapeChars = {{'\n', "\\n"}, {'\r', "\\r"}, {'\t', "\\t"}, {'\a', "\\a"}, {'\b', "\\b"}, {'\f', "\\f"}, {'\v', "\\v"}, {'\"', "\\\""}, {'\'', "\\\'"}, {'\\', "\\\\"}};

    for (size_t i = 0; i < value.length(); ++i) {
        char ch = value[i];
        auto it = escapeChars.find(ch);
        if (it != escapeChars.end()) {
            escapeValue += it->second;
        } else {
            escapeValue += ch;
        }
    }
    return escapeValue;
}

/// 去除所有的转义字符
static std::string RemoveAllEscapeTokens(const std::string &value) {
    static std::map<char, std::string> escapeChars = {{'n', "\n"}, {'r', "\r"}, {'t', "\t"}, {'a', "\a"}, {'b', "\b"}, {'f', "\f"}, {'v', "\v"}};

    std::string result = "";
    // 双引号""：会将特殊字符转义为本身想表示的意思。
    bool escape = false;
    for (uint i = 0; i < value.size(); i++) {
        char c = value[i];
        if (escape) {
            auto it = escapeChars.find(c);
            if (it != escapeChars.end()) {
                result += it->second;
            } else {
                result += c;
            }
            escape = false;
        } else if (c == '\\') {
            escape = true;
        } else {
            result += c;
        }
    }
    return result;
}

YamlNode::YamlNode() {
    m_nodeType = YamlNode::None;
    m_hasComment = false;
    m_keyQuoteChar = YAML_QuoteCharNone;
    m_valueQuoteChar = YAML_QuoteCharNone;
    m_nodeValue = "";
    m_nodeKey = "";
    m_isFlow = false;
}

YamlNode::YamlNode(YamlNode &node) :
    YamlNode() {
    *this = node;
}

YamlNode::YamlNode(const std::string &value) :
    YamlNode() {
    *this = value;
}

YamlNode::YamlNode(const char *value) :
    YamlNode() {
    *this = value;
}

YamlNode::~YamlNode() {
    clean();
}

void YamlNode::clean() {
    for (YamlNode *node : m_subNodes) { delete node; }
    m_subNodes.clear();
    m_nodeType = YamlNode::None;
    m_nodeKey = "";
    m_nodeValue = "";
    m_keyQuoteChar = YAML_QuoteCharNone;
    m_valueQuoteChar = YAML_QuoteCharNone;
    m_comment = "";
    m_hasComment = false;
    m_isFlow = false;
    m_isBlockScalar = false;
    m_blockFlags = 0;
}

YamlNode &YamlNode::operator=(YamlNode &node) {
    clean();
    CopyNode(node, *this);
    return *this;
}

YamlNode &YamlNode::operator=(const std::string &value) {
    initScalar();
    if (m_nodeType == YamlNode::Scalar) {
        m_nodeValue = value;
    }
    return *this;
}

YamlNode &YamlNode::operator=(const char *value) {
    initScalar();
    if (m_nodeType == YamlNode::Scalar) {
        m_nodeValue = value ? std::string(value) : "";
    }
    return *this;
}

YamlNode &YamlNode::operator=(bool value) {
    initScalar();
    if (m_nodeType == YamlNode::Scalar) {
        m_nodeValue = value ? "true" : "false";
    }
    return *this;
}

void YamlNode::CopyNode(const YamlNode &from, YamlNode &to) {
    to.clean();
    AppendToNode(from, to);
}

void YamlNode::AppendToNode(const YamlNode &from, YamlNode &to) {
    auto copyKeyParams = [](const YamlNode &subFrom, YamlNode &subTo) {
        subTo.setNodeType(subFrom.nodeType());
        subTo.setIsFlow(subFrom.isFlow());
        subTo.setIsBlockScalar(subFrom.isBlockScalar());
        subTo.setBlockFlags(subFrom.blockFlags());
        subTo.setNodeKey(subFrom.nodeKey());
        subTo.setKeyQuoteChar(subFrom.keyQuoteChar());
        subTo.setComment(subFrom.comment());
        subTo.setHasComment(subFrom.hasComment());
    };
    auto copyAllParams = [&copyKeyParams](const YamlNode &subFrom, YamlNode &subTo) {
        copyKeyParams(subFrom, subTo);
        subTo.setNodeValue(subFrom.nodeValue());
        subTo.setValueQuoteChar(subFrom.valueQuoteChar());
    };
    auto copySubNode = [&copyAllParams, &copyKeyParams](const YamlNode &from, YamlNode &to) {
        if (from.isMap() || from.isSequence()) {
            copyKeyParams(from, to);
            for (auto it = from.m_subNodes.begin(); it != from.m_subNodes.end(); it++) {
                auto &currentNode = **it;
                YamlNode &newNode = to.addSubNode();
                if (currentNode.isMap() || currentNode.isSequence()) {
                    AppendToNode(currentNode, newNode);
                } else {
                    copyAllParams(currentNode, newNode);
                }
            }
        } else {
            copyAllParams(from, to);
        }
    };

    to.setNodeType(from.nodeType());
    to.setIsFlow(from.isFlow());
    to.setIsBlockScalar(from.isBlockScalar());
    to.setComment(from.comment());
    to.setHasComment(from.hasComment());
    for (auto it = from.m_subNodes.begin(); it != from.m_subNodes.end(); it++) {
        YamlNode &newNode = to.addSubNode();
        copySubNode(**it, newNode);
    }
}
std::string YamlNode::asString() const {
    if (m_nodeType == YamlNode::Scalar) {
        return m_nodeValue;
    }
    return g_EmptyString;
}

std::string YamlNode::asString(const std::string &defaultValue) const {
    if (m_nodeType == YamlNode::Scalar) {
        return m_nodeValue;
    }
    return defaultValue;
}

std::pair<bool, std::string> YamlNode::asStringPair(const std::string &defaultValue) const {
    return asPair(defaultValue);
}

int YamlNode::asInt() const {
    if (m_nodeType == YamlNode::Scalar) {
        return as<int>();
    }
    return 0;
}

int YamlNode::asInt(int defaultValue) const {
    return as<int>(defaultValue);
}

std::pair<bool, int> YamlNode::asIntPair(int defaultValue) const {
    return asPair(defaultValue);
}

long YamlNode::asLong() const {
    if (m_nodeType == YamlNode::Scalar) {
        return as<int>();
    }
    return 0;
}

long YamlNode::asLong(long defaultValue) const {
    return as<int>(defaultValue);
}

std::pair<bool, long> YamlNode::asLongPair(long defaultValue) const {
    return asPair(defaultValue);
}

long long YamlNode::asLongLong() const {
    if (m_nodeType == YamlNode::Scalar) {
        return as<int>();
    }
    return 0;
}

long long YamlNode::asLongLong(long long defaultValue) const {
    return as<long long>(defaultValue);
}

std::pair<bool, long long> YamlNode::asLongLongPair(long long defaultValue) const {
    return asPair(defaultValue);
}

uint YamlNode::asUInt() const {
    if (m_nodeType == YamlNode::Scalar) {
        return as<uint>();
    }
    return 0;
}

uint YamlNode::asUInt(uint defaultValue) const {
    return as<uint>(defaultValue);
}

std::pair<bool, uint> YamlNode::asUIntPair(uint defaultValue) const {
    return asPair(defaultValue);
}

ulong YamlNode::asULong() const {
    if (m_nodeType == YamlNode::Scalar) {
        return as<uint>();
    }
    return 0;
}

ulong YamlNode::asULong(ulong defaultValue) const {
    return as<uint>(defaultValue);
}

std::pair<bool, ulong> YamlNode::asULongPair(ulong defaultValue) const {
    return asPair(defaultValue);
}

double YamlNode::asDouble() const {
    if (m_nodeType == YamlNode::Scalar) {
        return as<double>();
    }
    return 0;
}

double YamlNode::asDouble(double defaultValue) const {
    return as<double>(defaultValue);
}

std::pair<bool, double> YamlNode::asDoublePair(double defaultValue) const {
    return asPair(defaultValue);
}

bool YamlNode::asBool() const {
    if (m_nodeType == YamlNode::Scalar) {
        return as<bool>();
    }
    return false;
}

bool YamlNode::asBool(bool defaultValue) const {
    return as<bool>(defaultValue);
}

std::pair<bool, bool> YamlNode::asBoolPair(bool defaultValue) const {
    return asPair(defaultValue);
}

YamlNode::NodeType YamlNode::nodeType() const {
    return m_nodeType;
}

size_t YamlNode::allSize() const {
    return m_subNodes.size();
}

size_t YamlNode::size() const {
    size_t size = 0;
    for (auto it = m_subNodes.begin(); it != m_subNodes.end(); it++) {
        if (!(*it)->isEmptyLine()) {
            size++;
        }
    }
    return size;
}

YamlNodeIterator YamlNode::begin() {
    YamlNodeIterator it;
    it.initBegin(this);
    return it;
}

YamlNodeIterator YamlNode::end() {
    YamlNodeIterator it;
    it.initEnd(this);
    return it;
}

YamlNodeIterator YamlNode::rbegin() {
    YamlNodeIterator it;
    it.initRBegin(this);
    return it;
}

YamlNodeIterator YamlNode::rend() {
    YamlNodeIterator it;
    it.initREnd(this);
    return it;
}

YamlNodeIterator YamlNode::erase(YamlNodeIterator &it) {
    YamlNodeIterator newIT = it;

    auto itBase = it.m_isRInterator ? it.m_RIterator.base() : it.m_Iterator;
    if (itBase != m_subNodes.end()) {
        newIT++;
        delete *itBase;
        m_subNodes.erase(itBase);
    }

    return newIT;
}

void YamlNode::erase(const size_t index) {
    if (index < m_subNodes.size()) {
        auto it = m_subNodes.begin();
        std::advance(it, index); // 将迭代器移动到指定位置
        if (it != m_subNodes.end()) {
            delete *it;
            m_subNodes.erase(it);
        }
    }
}
void YamlNode::erase(const std::string &key) {
    if (m_nodeType == YamlNode::Map) {
        for (auto it = m_subNodes.begin(); it != m_subNodes.end();) {
            if ((*it)->nodeKey() == key) {
                delete *it;
                it = m_subNodes.erase(it);
            } else {
                ++it;
            }
        }
    }
}

bool YamlNode::erase(YamlNode &node) {
    for (auto it = m_subNodes.begin(); it != m_subNodes.end();) {
        if ((*it) == &node) {
            delete *it;
            m_subNodes.erase(it);
            return true;
        } else {
            ++it;
        }
    }
    return false;
}

bool YamlNode::moveToEnd(const size_t index) {
    if (index >= m_subNodes.size()) {
        return false;
    }
    auto it = m_subNodes.begin();
    std::advance(it, index);    // 将迭代器移动到指定位置
    YamlNode *node = *it;       // 保存要移动的节点
    m_subNodes.erase(it);       // 从当前位置移除
    m_subNodes.push_back(node); // 添加到末尾
}

bool YamlNode::moveToEnd(YamlNodeIterator &it) {
    auto itBase = it.m_isRInterator ? it.m_RIterator.base() : it.m_Iterator;
    if (itBase == m_subNodes.end()) {
        return false;
    }
    YamlNode *node = &(*it).second;
    m_subNodes.erase(itBase);
    m_subNodes.push_back(node); // 添加到末尾
}

YamlNode &YamlNode::pushFront() {
    YamlNode *pNode = new YamlNode;
    m_subNodes.push_front(pNode);
    return *pNode;
}
YamlNode &YamlNode::pushBack(bool pushBeforeEmptyLine) {
    YamlNode *pNode = new YamlNode;
    if (pushBeforeEmptyLine) {
        insertNodeAfterNotEmptyLine(pNode);
    } else {
        m_subNodes.push_back(pNode);
    }
    return *pNode;
}

YamlNode &YamlNode::pushEmptyLine() {
    YamlNode *pNode = new YamlNode();
    pNode->initEmptyLine();
    m_subNodes.push_back(pNode);
    return *pNode;
}

YamlNode &YamlNode::insert(size_t index) {
    YamlNode *pNode = new YamlNode;
    if (index >= m_subNodes.size()) {
        m_subNodes.push_back(pNode);
    } else {
        auto it = m_subNodes.begin();
        std::advance(it, index);
        m_subNodes.insert(it, pNode);
    }
    return *pNode;
}

YamlNode &YamlNode::insertBefore(YamlNode &node) {
    for (auto it = m_subNodes.begin(); it != m_subNodes.end();) {
        if ((*it) == &node) {
            YamlNode *pNode = new YamlNode;
            m_subNodes.insert(it, pNode);
            return *pNode;
        } else {
            ++it;
        }
    }
    // 在最前面插入
    YamlNode *pNode = new YamlNode;
    m_subNodes.insert(m_subNodes.begin(), pNode);
    return *pNode;
}

YamlNode &YamlNode::operator[](const size_t index) {
    initSequence();
    size_t validIndex = 0;
    for (YamlNode *node : m_subNodes) {
        if (!node->isEmptyLine()) {
            if (validIndex == index) {
                return *node;
            }
            validIndex++;
        }
    }
    YamlNode *pNode = new YamlNode;
    m_subNodes.push_back(pNode);
    return *pNode;
}

YamlNode &YamlNode::operator[](const std::string &key) {
    initMap();
    for (YamlNode *node : m_subNodes) {
        if (!node->isEmptyLine() && node->nodeKey() == key) {
            return *node;
        }
    }
    YamlNode *pNode = new YamlNode;
    pNode->setNodeKey(key);
    m_subNodes.push_back(pNode);
    return *pNode;
}

std::vector<std::string> YamlNode::getSubNodeKeyList() {
    std::vector<std::string> keyList;
    for (YamlNode *node : m_subNodes) {
        if (!node->isEmptyLine()) {
            keyList.push_back(node->nodeKey());
        }
    }
    return keyList;
}

bool YamlNode::hasSubNode(const std::string &key, bool recursiveCheck) {
    if (recursiveCheck) {
        return hasSubNode(SplitStr(key));
    } else {
        std::string trimmedKey = Trim(key);
        for (YamlNode *node : m_subNodes) {
            if (!node->isEmptyLine() && node->nodeKey() == trimmedKey) {
                return true;
            }
        }
        return false;
    }
}

bool YamlNode::hasSubNode(const std::vector<std::string> &keyList) {
    if (keyList.size() > 0) {
        std::string currentKey = keyList[0];
        currentKey = Trim(currentKey);
        for (YamlNode *node : m_subNodes) {
            if (!node->isEmptyLine() && node->nodeKey() == currentKey) {
                if (keyList.size() > 1) {
                    std::vector<std::string> subKeyList = std::vector<std::string>(keyList.begin() + 1, keyList.end());
                    return node->hasSubNode(subKeyList);
                } else {
                    return true;
                }
            }
        }
    }
    return false;
}

YamlNode &YamlNode::getSubNode(const std::string &key, bool recursiveCheck) {
    if (recursiveCheck) {
        return getSubNode(SplitStr(key));
    } else {
        std::string trimmedKey = Trim(key);
        for (YamlNode *node : m_subNodes) {
            if (!node->isEmptyLine() && node->nodeKey() == trimmedKey) {
                return *node;
            }
        }
        g_NoneNode.clean();
        return g_NoneNode;
    }
}

YamlNode &YamlNode::getSubNode(const std::vector<std::string> &keyList) {
    if (keyList.size() > 0) {
        std::string currentKey = keyList[0];
        currentKey = Trim(currentKey);
        for (YamlNode *node : m_subNodes) {
            if (!node->isEmptyLine() && node->nodeKey() == currentKey) {
                if (keyList.size() > 1) {
                    std::vector<std::string> subKeyList = std::vector<std::string>(keyList.begin() + 1, keyList.end());
                    return node->getSubNode(subKeyList);
                } else {
                    return *node;
                }
            }
        }
    }
    g_NoneNode.clean();
    return g_NoneNode;
}

YamlNode &YamlNode::getSubNode(const size_t index, bool onlyValidNode) {
    if (index < m_subNodes.size()) {
        if (onlyValidNode) {
            size_t validIndex = 0;
            for (YamlNode *node : m_subNodes) {
                if (!node->isEmptyLine()) {
                    if (validIndex == index) {
                        return *node;
                    }
                    validIndex++;
                }
            }
        } else {
            auto it = m_subNodes.begin();
            std::advance(it, index);
            if (it != m_subNodes.end()) {
                return **it;
            }
        }
    }
    g_NoneNode.clean();
    return g_NoneNode;
}

bool YamlNode::isNone() const {
    return m_nodeType == YamlNode::None;
}

bool YamlNode::isEmptyLine() const {
    return m_nodeType == YamlNode::EmptyLine;
}

bool YamlNode::isSequence() const {
    return m_nodeType == YamlNode::Sequence;
}
bool YamlNode::isFlowSequence() const {
    return m_nodeType == YamlNode::Sequence && isFlow();
}

bool YamlNode::isMap() const {
    return m_nodeType == YamlNode::Map;
}

bool YamlNode::isFlowMap() const {
    return m_nodeType == YamlNode::Map && isFlow();
}

bool YamlNode::isScalar() const {
    return m_nodeType == YamlNode::Scalar;
}

bool YamlNode::isFlow() const {
    return m_isFlow;
}

void YamlNode::setIsFlow(bool value) {
    m_isFlow = value;
    // 遍历所有子节点，同步流式标志
    for (YamlNode *node : m_subNodes) {
        node->setIsFlow(value);
    }
}

std::string YamlNode::nodeKey() const {
    return m_nodeKey;
}

void YamlNode::setNodeKey(const std::string &value) {
    m_nodeKey = value;
}

std::string YamlNode::nodeValue() const {
    return m_nodeValue;
}

void YamlNode::setNodeValue(const std::string &nodeValue) {
    m_nodeValue = nodeValue;
}

std::string YamlNode::comment() const {
    return m_comment;
}

void YamlNode::setComment(const std::string &value) {
    m_comment = value;
    setHasComment(!value.empty());
}

bool YamlNode::hasComment() const {
    return m_hasComment;
}

void YamlNode::setHasComment(bool hasComment) {
    m_hasComment = hasComment;
}

bool YamlNode::hasKeyQuoteChar() const {
    return m_keyQuoteChar != YAML_QuoteCharNone;
}

char YamlNode::keyQuoteChar() const {
    return m_keyQuoteChar;
}

void YamlNode::setKeyQuoteChar(char quoteChar) {
    m_keyQuoteChar = quoteChar;
}

bool YamlNode::hasValueQuoteChar() const {
    return m_valueQuoteChar != YAML_QuoteCharNone;
}

char YamlNode::valueQuoteChar() const {
    return m_valueQuoteChar;
}

void YamlNode::setValueQuoteChar(char quoteChar) {
    m_valueQuoteChar = quoteChar;
}

bool YamlNode::isBlockScalar() const {
    return m_isBlockScalar;
}

void YamlNode::setIsBlockScalar(bool isBlockScalar) {
    m_isBlockScalar = isBlockScalar;
}

char YamlNode::blockFlags() const {
    return m_blockFlags;
}

void YamlNode::setBlockFlags(char blockFlags) {
    m_blockFlags = blockFlags;
}

void YamlNode::setNodeType(YamlNode::NodeType type) {
    this->m_nodeType = type;
}

void YamlNode::initEmptyLine() {
    m_nodeType = YamlNode::EmptyLine;
}

void YamlNode::initSequence() {
    m_nodeType = YamlNode::Sequence;
}

void YamlNode::initMap() {
    m_nodeType = YamlNode::Map;
}

void YamlNode::initScalar() {
    m_nodeType = YamlNode::Scalar;
}

bool YamlNode::moveFrontEmptyLineToEnd() {
    size_t allSize = m_subNodes.size();
    size_t moveNum = 0;
    while (moveNum < allSize) {
        YamlNode *frontNode = m_subNodes.front();
        if (frontNode->isEmptyLine()) {
            m_subNodes.pop_front();          // 从当前位置移除
            m_subNodes.push_back(frontNode); // 添加到末尾
            moveNum++;
        } else {
            break;
        }
    }
    return true;
}

YamlNode &YamlNode::addSubNode() {
    YamlNode *pNode = new YamlNode;
    m_subNodes.push_back(pNode);
    return *pNode;
}

void YamlNode::insertNodeAfterNotEmptyLine(YamlNode *pNode) {
    auto rit = m_subNodes.rbegin();
    while (rit != m_subNodes.rend()) {
        if (!(*rit)->isEmptyLine()) {
            m_subNodes.insert((rit.base()++), pNode);
            return;
        }
        ++rit;
    }
    if (rit == m_subNodes.rend()) {
        m_subNodes.push_front(pNode);
    }
}

/// YAML行读取，保存文件每行的信息
class ReaderLine {
public:
    ReaderLine(const std::string &data = "", const size_t lineNo = 0, const size_t offset = 0, const YamlNode::NodeType type = YamlNode::None, const unsigned char flags = 0) :
        Data(data), LineNo(lineNo), Offset(offset), Type(type), Flags(flags), DataQuoteChar(YAML_QuoteCharNone) {
    }

    enum LineFlag {
        LiteralScalarFlag = 1, ///< 多行排版字符串, 以 "|" 开头，保留换行符
        FoldedScalarFlag = 2,  ///< 多行字符串, 以 "<" 开头，将换行转换为空格
        ScalarNewlineFlag = 4, ///< 标识开始一个多行字符串
        FlagAll = 7            /// Flag全选
    };

    /// 设置行标识
    void setFlag(const LineFlag flag) {
        Flags |= flag;
    }

    /// 通过掩码设置标识
    void setFlag(const unsigned char flags) {
        Flags |= flags;
    }

    /// 取消标识
    void unsetFlag(const LineFlag flag) {
        Flags &= ~flag;
    }

    /// 通过掩码取消标识
    void unsetFlag(const unsigned char flags) {
        Flags &= ~flags;
    }

    /// 是否设置指定标识
    bool hasFlag(const LineFlag flag) const {
        return Flags & flag;
    }

    /// 从另一个 ReaderLine 复制并替换标量标志。
    void copyScalarFlags(ReaderLine *from) {
        if (from != nullptr) {
            Flags |= (from->Flags & FlagAll);
        }
    }

    std::string Data;        ///< 行字符串内容
    char DataQuoteChar;      ///< Data的引号
    size_t LineNo;           ///< 行号
    size_t Offset;           ///< 行绝对偏移量，即首字符出现位置
    YamlNode::NodeType Type; ///< 行类型
    unsigned char Flags;     ///< 行标识
    std::string Comment;     ///< 行末注释
    bool HasComment;         ///< 是否有注释，注释可能是空
};

/// 迭代器
YamlNodeIterator::YamlNodeIterator() :
    m_Type(YamlNode::None), m_isRInterator(false) {
}

YamlNodeIterator::YamlNodeIterator(const YamlNodeIterator &it) :
    YamlNodeIterator() {
    *this = it;
}

YamlNodeIterator &YamlNodeIterator::operator=(const YamlNodeIterator &it) {
    m_Type = it.m_Type;
    m_Iterator = it.m_Iterator;
    m_RIterator = it.m_RIterator;
    m_isRInterator = it.m_isRInterator;

    return *this;
}

YamlNodeIterator::~YamlNodeIterator() {
}

std::pair<const std::string &, YamlNode &> YamlNodeIterator::operator*() {
    switch (m_Type) {
    case YamlNode::EmptyLine:
    case YamlNode::Sequence:
    case YamlNode::Scalar: return {g_EmptyString, m_isRInterator ? (**m_RIterator) : (**m_Iterator)}; break;
    case YamlNode::Map: {
        YamlNode *node = m_isRInterator ? (*m_RIterator) : (*m_Iterator);
        return {node->nodeKey(), *(node)};
        break;
    }
    default: break;
    }

    g_NoneNode.clean();
    return {g_EmptyString, g_NoneNode};
}

YamlNodeIterator &YamlNodeIterator::operator++(int dummy) {
    if (m_isRInterator) {
        m_RIterator++;
    } else {
        m_Iterator++;
    }
    return *this;
}

YamlNodeIterator &YamlNodeIterator::operator--(int dummy) {
    if (m_isRInterator) {
        m_RIterator--;
    } else {
        m_Iterator--;
    }
    return *this;
}

bool YamlNodeIterator::operator==(const YamlNodeIterator &it) {
    if (m_isRInterator != it.m_isRInterator) {
        return false;
    }
    if (m_isRInterator) {
        return m_RIterator == it.m_RIterator;
    } else {
        return m_Iterator == it.m_Iterator;
    }
}

bool YamlNodeIterator::operator!=(const YamlNodeIterator &it) {
    return !(*this == it);
}

void YamlNodeIterator::initBegin(YamlNode *imp) {
    if (imp) {
        m_Type = imp->nodeType();
        m_isRInterator = false;
        m_Iterator = imp->m_subNodes.begin();
    }
}

void YamlNodeIterator::initEnd(YamlNode *imp) {
    if (imp) {
        m_Type = imp->nodeType();
        m_isRInterator = false;
        m_Iterator = imp->m_subNodes.end();
    }
}

void YamlNodeIterator::initRBegin(YamlNode *imp) {
    if (imp) {
        m_Type = imp->nodeType();
        m_isRInterator = true;
        m_RIterator = imp->m_subNodes.rbegin();
    }
}

void YamlNodeIterator::initREnd(YamlNode *imp) {
    if (imp) {
        m_Type = imp->nodeType();
        m_isRInterator = true;
        m_RIterator = imp->m_subNodes.rend();
    }
}

/// Yaml的解析类。解析传入流并输出根节点。
class ParseImp {
public:
    ParseImp() {
    }

    ~ParseImp() {
        clearLines();
    }

    /// 开始解析YAML
    void Parse(YamlNode &rootNode, std::iostream &stream, bool ignoreEmptyLine = YAML_IgnoreEmptyLineDefault, bool printLines = YAML_PrintLinesDefault) {
        try {
            rootNode.clean();
            readLines(stream, ignoreEmptyLine);
            postProcessLines();
            if (printLines) {
                print();
            }
            parseRoot(rootNode);
            analysFlowScalar(rootNode);
        } catch (std::runtime_error e) {
            rootNode.clean();
            throw;
        }
    }

private:
    ParseImp(const ParseImp &copy) {
    }

    /// 行是否是序列行，以-加空格开头
    static bool IsSequenceStart(const std::string &data) {
        if (data.size() == 0 || data[0] != '-') {
            return false;
        }

        if (data.size() >= 2 && data[1] != ' ') {
            return false;
        }

        return true;
    }

    /// 检查是否是块标量
    static bool IsBlockScalar(const std::string &data, const size_t line, char &flags) {
        flags = 0;
        if (data.size() == 0) {
            return false;
        }

        if (data[0] == '|') {       // 如果字符串的第一个字符是|，则可能是一个字面量区块标量
            if (data.size() >= 2) { // 如果字符串长度至少为2，检查第二个字符是否为-、空格或制表符
                if (data[1] != '-' && data[1] != ' ' && data[1] != '\t') {
                    throw std::runtime_error(ExceptionMessage(g_errorInvalidBlockScalar, line, data));
                }
            } else {
                flags |= ReaderLine::ScalarNewlineFlag;
            }
            flags |= ReaderLine::LiteralScalarFlag;
            return true;
        }

        if (data[0] == '>') {
            if (data.size() >= 2) {
                if (data[1] != '-' && data[1] != ' ' && data[1] != '\t') {
                    throw std::runtime_error(ExceptionMessage(g_errorInvalidBlockScalar, line, data));
                }
            } else {
                flags |= ReaderLine::ScalarNewlineFlag;
            }
            flags |= ReaderLine::FoldedScalarFlag;
            return true;
        }

        return false;
    }

    /// 清除所有读取的行数据
    void clearLines() {
        for (auto it = m_Lines.begin(); it != m_Lines.end(); it++) {
            delete *it;
        }
        m_Lines.clear();
    }

    /// 1 预读取所有行
    void readLines(std::iostream &stream, bool ignoreEmptyLine = YAML_IgnoreEmptyLineDefault) {
        std::string line = "";
        size_t lineNo = 0;
        bool documentStartFound = false;
        std::streampos streamPos = 0;

        // 读所有的行
        while (!stream.eof() && !stream.fail()) {
            streamPos = stream.tellg();
            if (!std::getline(stream, line)) {
                break;
            }
            lineNo++;

            // 提取并移除注释
            std::string comment = "";
            bool hasComment = false;
            const size_t commentPos = FindNotCited(line, '#');
            if (commentPos != std::string::npos) {
                comment = line.substr(commentPos + 1);
                line.resize(commentPos); // 收缩值长度，去掉最后的注释部分
                hasComment = true;
            }

            // 开始文档
            if (documentStartFound == false && line == "---") {
                clearLines(); // 擦除之前加载的所有行
                documentStartFound = true;
                continue;
            }

            if (line == "...") {
                break; // 文档结束
            } else if (line == "---") {
                stream.seekg(streamPos);
                break;
            }

            if (line.size() && line[line.size() - 1] == '\r') {
                line.resize(line.size() - 1); // 删除行尾换行符。
            }

            // 找到第一个TAB位置和第一个有效字符位置
            const size_t firstTabPos = line.find_first_of('\t');
            size_t startOffset = line.find_first_not_of(" \t");

            if (startOffset != std::string::npos) {
                if (firstTabPos < startOffset) {
                    // 意味着在第一个有效字符之前存在TAB，这违反格式要求
                    throw std::runtime_error(ExceptionMessage(g_errorTabInOffset, lineNo, firstTabPos));
                }
                line = line.substr(startOffset); // 移除TAB前面的空白字符（空格TAB）
            } else {
                startOffset = 0;
                line = ""; // TAB后没有任何内容，作为空行
            }

            if (!hasComment && line.empty() && ignoreEmptyLine) {
                continue;
            }
            ReaderLine *pLine = new ReaderLine(line, lineNo, startOffset);
            pLine->Comment = RightTrim(comment); // 移除右侧特殊字符
            pLine->HasComment = hasComment;
            m_Lines.push_back(pLine);
        }
    }

    /// 2 读完行后，先梳理行类型并拆分子项
    void postProcessLines() {
        bool foundFirstNotEmpty = false; // 找到第一个非空行
        for (auto it = m_Lines.begin(); it != m_Lines.end();) {
            if (foundFirstNotEmpty == false) {
                ReaderLine *pLine = *it;
                if (pLine->Data.size()) {
                    foundFirstNotEmpty = true;
                } else {
                    pLine->Type = YamlNode::EmptyLine;
                    pLine->Offset = 0;
                    ++it;
                    continue;
                }
            }
            if (postProcessSequenceLine(it) == true) {
                continue;
            }
            if (postProcessMappingLine(it) == true) {
                continue;
            }
            postProcessScalarLine(it);
        }
    }

    /// 2.1 序列后处理
    /// \return 行是否是序列
    bool postProcessSequenceLine(std::list<ReaderLine *>::iterator &it) {
        if (it == m_Lines.end()) {
            return true;
        }
        ReaderLine *pLine = *it;

        // 检查序列头字符-
        if (IsSequenceStart(pLine->Data) == false) {
            return false;
        }

        pLine->Type = YamlNode::Sequence;

        const size_t valueStart = pLine->Data.find_first_not_of(" \t", 1); // 找该行的值开始位置
        if (valueStart == std::string::npos) {
            pLine->Data = "";
            postCheckTrailingEmptyLines(++it); // 跳过后续连续空行，并将空行追加到当前序列子对象中，以保持空行位置
            return true;                       // 没有值，即只有-
        }

        // 如果有值，将值插入到当前行下一行（作为元值）
        std::string newLine = pLine->Data.substr(valueStart);
        size_t newLineOffset = pLine->Offset + valueStart;
        ReaderLine *pNewLine = new ReaderLine(newLine, pLine->LineNo, newLineOffset);
        pNewLine->Comment = pLine->Comment; // 注释跟随元值行
        pNewLine->HasComment = pLine->HasComment;
        it = m_Lines.insert(++it, pNewLine);

        pLine->Data = "";
        pLine->Comment.clear();

        auto emptyCheckIT = it;
        postCheckTrailingEmptyLines(++emptyCheckIT); // 跳过后续连续空行，并将空行追加到当前序列子对象中，以保持空行位置

        if ((*emptyCheckIT)->Offset < newLineOffset) {
            return true;
        }
        return false; // 元值可能是map形式，所以需要进一步检查是否是map，如[- a: 1]
    }

    /// 2.2 map后处理，如果映射值不在自己的行上，则将行拆分为两行。
    /// \return 行是否是映射
    bool postProcessMappingLine(std::list<ReaderLine *>::iterator &it) {
        if (it == m_Lines.end()) {
            return true;
        }
        ReaderLine *pLine = *it;

        size_t preKeyQuotes = 0;
        size_t tokenPos = FindNotCited(pLine->Data, ':', preKeyQuotes); // 找到不在引号中的冒号位置，来分隔KEY和VALUE
        if (tokenPos == std::string::npos) {
            return false;
        }
        if (preKeyQuotes > 1) {
            // 冒号前超过一对闭合引号,这是错的，最多一对或没有，即冒号前是KEY，可以被引号包裹或无引号，但不可能有多个绰号对
            throw std::runtime_error(ExceptionMessage(g_errorKeyIncorrect, *pLine));
        }

        pLine->Type = YamlNode::Map;

        // 取key部分
        std::string key = pLine->Data.substr(0, tokenPos);
        char keyQuoteChar = YAML_QuoteCharNone;
        const size_t keyEnd = key.find_last_not_of(" \t"); // 找key的最后一个有效字符;
        if (keyEnd == std::string::npos) {                 // KEY为空
            throw std::runtime_error(ExceptionMessage(g_errorKeyMissing, *pLine));
        }
        key.resize(keyEnd + 1); // 调整key的长度，去除尾部的空白字符

        if (preKeyQuotes == 1) {
            bool rightQuote = (key.front() == '"' && key.back() == '"') || (key.front() == '\'' && key.back() == '\'');
            if (!rightQuote) {
                throw std::runtime_error(ExceptionMessage(g_errorKeyIncorrect, *pLine));
            }
            keyQuoteChar = key.front();
            key = key.substr(1, key.size() - 2); // 去除key的首尾引号
        }
        if (keyQuoteChar == '\"') {
            key = RemoveAllEscapeTokens(key);
        }

        // 取value部分
        std::string value = "";
        size_t valueStart = std::string::npos;
        if (tokenPos + 1 != pLine->Data.size()) {
            // 如果冒号后还有内容，找到值的开始位置，并提取值
            valueStart = pLine->Data.find_first_not_of(" \t", tokenPos + 1);
            if (valueStart != std::string::npos) {
                value = pLine->Data.substr(valueStart);
            }
        }

        // value不能是序列，不允许[key: - value]这种形式
        if (IsSequenceStart(value) == true) {
            throw std::runtime_error(ExceptionMessage(g_errorBlockSequenceNotAllowed, *pLine, valueStart));
        }

        pLine->Data = key; // 当前行保存key，后面会添加新行保存value
        pLine->DataQuoteChar = keyQuoteChar;

        bool moveCommentToValue = false;
        size_t newLineOffset = valueStart;
        if (valueStart == std::string::npos) {
            postCheckTrailingEmptyLines(++it); // 追加尾随连续空行
            if (it == m_Lines.end() || (*it)->Offset > pLine->Offset) {
                newLineOffset = tokenPos + 2; // 如果没有value，下一行是自己的子节点，故在KEY位置偏移增加一级+2
            }
            return true;
        } else {
            moveCommentToValue = true;
            newLineOffset += pLine->Offset; // 如果有value，下一级偏移与本行的value起始位置对齐
        }

        // 将value拆分并添加到下一行
        ReaderLine *pNewLine = new ReaderLine(value, pLine->LineNo, newLineOffset, YamlNode::Scalar);
        if (moveCommentToValue) {
            pNewLine->Comment = pLine->Comment;
            pNewLine->HasComment = pLine->HasComment;
            pLine->Comment.clear();
            pLine->HasComment = false;
        }
        it = m_Lines.insert(++it, pNewLine);
        postCheckTrailingEmptyLines(++it); // 追加尾随连续空行

        if (it == m_Lines.end() || (*it)->Offset < newLineOffset) {
            return true;
        }
        return false;
    }

    /// 2.3 标量后处理，检查多行标量。
    void postProcessScalarLine(std::list<ReaderLine *>::iterator &it) {
        if (it == m_Lines.end()) {
            return;
        }
        ReaderLine *pLine = *it;
        it++;
        pLine->Type = YamlNode::Scalar;

        size_t parentOffset = pLine->Offset;
        if (pLine != m_Lines.front()) {
            std::list<ReaderLine *>::iterator lastIt = it;
            --lastIt;
            parentOffset = (*lastIt)->Offset; // 取上一行的偏移
        }

        // 标记尾随空行
        while (it != m_Lines.end()) {
            pLine = *it;
            if (pLine->Data.empty()) {
                pLine->Type = YamlNode::EmptyLine;
            } else {
                pLine->Type = YamlNode::Scalar;
                if (pLine->Offset <= parentOffset) {
                    break; // 找到下一个与父节点同级或更高一级的节点
                }
            }
            ++it;
        }
    }

    /// 3 分析各行数据，并转存至节点树中
    /// \param rootNode 存放所有YAML内容的根节点
    void parseRoot(YamlNode &rootNode) {
        auto it = m_Lines.begin();
        while (it != m_Lines.end()) {
            YamlNode::NodeType type = (*it)->Type;

            switch (type) {
            case YamlNode::EmptyLine: parseEmptyLine(rootNode, it); break;
            case YamlNode::Sequence:
            case YamlNode::Map: parseSequenceOrMap(rootNode, it); break;
            case YamlNode::Scalar: parseScalar(rootNode, it); break;
            default: break;
            }
        }

        if (it != m_Lines.end()) {
            ReaderLine *pLine = *it;
            throw std::runtime_error(ExceptionMessage(g_errorUnexpectedDocumentEnd, *pLine));
        }
    }

    /// 3.1 分析空行
    void parseEmptyLine(YamlNode &node, std::list<ReaderLine *>::iterator &it) {
        while (it != m_Lines.end()) {
            ReaderLine *pLine = *it;
            if (pLine->Type == YamlNode::EmptyLine) {
                YamlNode &childNode = node.pushEmptyLine();
                childNode.setComment(pLine->Comment);
                childNode.setHasComment(pLine->HasComment);
                ++it;
            } else {
                break;
            }
        }
    }

    /// 3.2 分析序列行
    void parseSequenceOrMap(YamlNode &node, std::list<ReaderLine *>::iterator &it) {
        ReaderLine *pNextLine = nullptr;
        YamlNode::NodeType nodeType = (*it)->Type;
        bool isMap = nodeType == YamlNode::Map;
        bool isSequence = nodeType == YamlNode::Sequence;
        if (!isMap && !isSequence) {
            return;
        }
        while (it != m_Lines.end()) {
            ReaderLine *pLine = *it;
            ++it;
            auto pLineNextIT = it;

            if (!isMap) {
                node.initSequence();
            }
            YamlNode &childNode = isMap ? node[pLine->Data] : node.pushBack(false);
            if (isMap) {
                childNode.initMap();
                childNode.setKeyQuoteChar(pLine->DataQuoteChar);
            } else {
                childNode.initSequence();
            }
            childNode.setComment(pLine->Comment);
            childNode.setHasComment(pLine->HasComment);

            if (it == m_Lines.end()) {
                return; // 说明最后一个是空值序列或空值map
            }
            if ((*it)->Type == YamlNode::EmptyLine) {
                parseEmptyLine(childNode, it); // 处理key:\n空行这种情况
            }

            if (it == m_Lines.end()) {
                return; // 文档末尾全是空行
            }
            if ((*it)->Offset < pLine->Offset) {
                return; // 下个节点缩进小，不再属于node
            } else if ((*it)->Offset == pLine->Offset) {
                continue; // 下个节点与当前节点平级，属于node
            } else {
                YamlNode::NodeType valueType = (*it)->Type;

                switch (valueType) {
                case YamlNode::EmptyLine:
                    parseEmptyLine(childNode, it);
                    break;
                case YamlNode::Sequence:
                case YamlNode::Map: parseSequenceOrMap(childNode, it); break;
                case YamlNode::Scalar: parseScalar(childNode, it); break;
                default: break;
                }
                if (it == m_Lines.end()) {
                    return;
                } else {
                    if ((*it)->Type == YamlNode::EmptyLine) {
                        parseEmptyLine(childNode, it); // 处理- \n空行和key:value\n空行这种情况
                    }
                    if (it == m_Lines.end()) {
                        return; // 下个节点为空
                    }
                    pNextLine = *it;
                    if (pNextLine->Offset < pLine->Offset) {
                        return; // 下个节点缩进小，不再属于node
                    } else if (pNextLine->Offset == pLine->Offset) {
                        if (pLineNextIT == it && pNextLine->Type != pLine->Type) { // 同级的节点类型应该相同
                            throw std::runtime_error(ExceptionMessage(g_errorDiffEntryNotAllowed, *pNextLine));
                        } else {
                            continue; // 下个节点与当前节点平级，属于node
                        }
                    } else {
                        // 说明子节点未完全处理完
                        throw std::runtime_error(ExceptionMessage(g_errorIncorrectOffset, *pNextLine));
                    }
                }
            }
        }
    }

    /// 3.3 分析元值行
    void parseScalar(YamlNode &node, std::list<ReaderLine *>::iterator &it) {
        std::string data = "";
        ReaderLine *pFirstLine = *it;
        ReaderLine *pLine = *it;

        // 检查当前行是否为块标量。
        char blockFlags = 0;
        bool isBlockScalar = IsBlockScalar(pLine->Data, pLine->LineNo, blockFlags);
        const bool newLineFlag = static_cast<bool>(blockFlags & ReaderLine::ScalarNewlineFlag);
        const bool foldedFlag = static_cast<bool>(blockFlags & ReaderLine::FoldedScalarFlag);
        const bool literalFlag = static_cast<bool>(blockFlags & ReaderLine::LiteralScalarFlag);
        size_t parentOffset = 0;

        node.setIsBlockScalar(isBlockScalar);
        node.setBlockFlags(blockFlags);

        // 父行的缩进偏移量
        if (it != m_Lines.begin()) {
            std::list<ReaderLine *>::iterator parentIt = it;
            --parentIt;
            parentOffset = (*parentIt)->Offset;
        }

        if (isBlockScalar) {
            ++it;
            if (it == m_Lines.end() || (pLine = *it)->Type != YamlNode::Scalar) {
                return;
            }
            pLine = *it;
            size_t blockOffset = pLine->Offset;
            if (blockOffset <= parentOffset) {
                throw std::runtime_error(ExceptionMessage(g_errorIncorrectOffset, *pLine));
            }

            bool addedSpace = false;
            while (it != m_Lines.end() && (*it)->Type == YamlNode::Scalar) {
                pLine = *it;

                const size_t endOffset = pLine->Data.find_last_not_of(" \t");
                if (endOffset != std::string::npos && pLine->Offset < blockOffset) {
                    throw std::runtime_error(ExceptionMessage(g_errorIncorrectOffset, *pLine));
                }

                if (endOffset == std::string::npos) {
                    if (addedSpace) {
                        data[data.size() - 1] = '\n';
                        addedSpace = false;
                    } else {
                        data += "\n";
                    }

                    ++it;
                    continue;
                } else {
                    if (blockOffset != pLine->Offset && foldedFlag) {
                        if (addedSpace) {
                            data[data.size() - 1] = '\n';
                            addedSpace = false;
                        } else {
                            data += "\n";
                        }
                    }
                    data += std::string(pLine->Offset - blockOffset, ' ');
                    data += pLine->Data;
                }

                ++it;
                if (it == m_Lines.end() || (*it)->Type != YamlNode::Scalar) {
                    if (newLineFlag) {
                        data += "\n";
                    }
                    break;
                }

                if (foldedFlag) {
                    data += " ";
                    addedSpace = true;
                } else if (literalFlag && endOffset != std::string::npos) {
                    data += "\n";
                }
            }
        } else {
            while (1) {
                pLine = *it;

                if (parentOffset != 0 && pLine->Offset <= parentOffset) {
                    throw std::runtime_error(ExceptionMessage(g_errorIncorrectOffset, *pLine));
                }

                const size_t endOffset = pLine->Data.find_last_not_of(" \t");
                if (endOffset == std::string::npos) {
                    data += "\n";
                } else {
                    data += pLine->Data.substr(0, endOffset + 1);
                }

                ++it;
                if (it == m_Lines.end() || (*it)->Type != YamlNode::Scalar) {
                    break;
                }
                data += " ";
            }
        }

        if (ValidateQuote(data) == false) {
            std::string trimmedData = Trim(data);
            if (!trimmedData.empty() && trimmedData != "\"\"") {
                // 再检查一下是否是否是流式结构
                YamlNode *tNode = analysFlowScalarLine(trimmedData);
                bool isFlow = tNode->isFlow();
                delete tNode;
                if (!isFlow) {
                    throw std::runtime_error(ExceptionMessage(g_errorInvalidQuote, *pFirstLine));
                }
            }
        }
        char quoteChar = YAML_QuoteCharNone; // 引号
        if (data.size() && (data[0] == '"' || data[0] == '\'')) {
            quoteChar = data[0];
            data = data.substr(1, data.size() - 2);
        }

        if (quoteChar == '\"') {
            data = RemoveAllEscapeTokens(data);
        }
        node = data;
        node.setComment(pLine->Comment);
        node.setHasComment(pLine->HasComment);
        node.setValueQuoteChar(quoteChar);
    }

    /// 4 寻找并处理可能的流式结点，如a:[1,2,3]，{a:1,b:2}
    void analysFlowScalar(YamlNode &node) {
        if (node.hasValueQuoteChar()) {
            return; // 如果值被引号包裹，就识为字符串，不要解析流式结构
        }
        switch (node.nodeType()) {
        case YamlNode::Sequence:
        case YamlNode::Map: {
            for (auto it = node.begin(); it != node.end(); it++) {
                YamlNode &subNode = (*it).second;
                analysFlowScalar(subNode);
            }
            break;
        }
        case YamlNode::Scalar: {
            std::string data = node.asString();
            YamlNode *lineNode = analysFlowScalarLine(data);
            if (lineNode->isFlow()) {
                lineNode->setComment(node.comment());
                node = "";
                YamlNode::AppendToNode(*lineNode, node);
                node.moveFrontEmptyLineToEnd(); // 将node的空行移至最后
            }
            delete lineNode;
            break;
        }
        }
    }

    /// 4.1 处理流式结点，如a:[1,2,3]，{a:1,b:2}
    YamlNode *analysFlowScalarLine(const std::string &data) {
        YamlNode *rootNode = new YamlNode();
        YamlNode *parentNode = rootNode;
        std::vector<YamlNode *> nodeTree;

        bool inQuotes = false;
        char quoteChar = YAML_QuoteCharNone;
        std::string currentValue;

        size_t i = 0;
        while (i < data.length()) {
            char c = data[i];
            switch (c) {
            case '[':
                if (!inQuotes) {
                    quoteChar = YAML_QuoteCharNone;
                    if (nodeTree.size() == 0) {
                        (*rootNode) = "";
                        rootNode->initSequence();
                        rootNode->setIsFlow(true);
                        nodeTree.push_back(rootNode);
                    } else if (parentNode->isScalar()) {
                        parentNode->initSequence();
                        parentNode->setIsFlow(true);
                    } else {
                        parentNode->initSequence();
                        parentNode->setIsFlow(true);
                        YamlNode &node = parentNode->pushBack(false);
                        node.initSequence();
                        node.setIsFlow(true);

                        parentNode = &node;
                        nodeTree.push_back(parentNode);
                    }
                }
                break;
            case ']':
                if (!inQuotes) {
                    if (parentNode->isFlowSequence()) {
                        if (!currentValue.empty()) {
                            parentNode->initSequence();
                            YamlNode &node = parentNode->pushBack(false);
                            node = currentValue;
                            node.setValueQuoteChar(quoteChar);
                            node.setIsFlow(true);
                            currentValue.clear();
                        }
                        nodeTree.pop_back();
                        parentNode = nodeTree.back();
                    }
                }
                break;

            case '{':
                if (!inQuotes) {
                    quoteChar = YAML_QuoteCharNone;
                    if (nodeTree.size() == 0) {
                        (*rootNode) = "";
                        rootNode->initMap();
                        rootNode->setIsFlow(true);
                        nodeTree.push_back(rootNode);
                    } else if (parentNode->isScalar()) {
                        parentNode->initMap();
                        parentNode->setIsFlow(true);
                    } else {
                        if (!parentNode->isSequence()) {
                            parentNode->initMap();
                            parentNode->setIsFlow(true);
                        }
                        YamlNode &node = parentNode->pushBack(false);
                        node.initMap();
                        node.setIsFlow(true);

                        parentNode = &node;
                        nodeTree.push_back(parentNode);
                    }
                }
                break;
            case '}':
                if (!inQuotes) {
                    if (!currentValue.empty()) {
                        if (parentNode->isScalar()) {
                            *parentNode = currentValue;
                            parentNode->setValueQuoteChar(quoteChar);
                            quoteChar = YAML_QuoteCharNone;
                            currentValue.clear();

                            nodeTree.pop_back();
                            parentNode = nodeTree.back();
                        }
                    }
                    if (parentNode->isFlowMap()) {
                        nodeTree.pop_back();
                        parentNode = nodeTree.back();
                    }
                }
                break;

            case ',':
                if (!inQuotes) {
                    // 结束当前元素，开始新元素
                    if (!currentValue.empty()) {
                        if (parentNode->isFlowSequence()) {
                            parentNode->initSequence();
                            YamlNode &node = parentNode->pushBack(false);
                            node.setIsFlow(true);
                            node.setValueQuoteChar(quoteChar);
                            quoteChar = YAML_QuoteCharNone;
                            node = currentValue;
                            currentValue.clear();
                        } else if (parentNode->isScalar()) {
                            *parentNode = currentValue;
                            parentNode->setValueQuoteChar(quoteChar);
                            quoteChar = YAML_QuoteCharNone;

                            currentValue.clear();

                            nodeTree.pop_back();
                            parentNode = nodeTree.back();
                        }
                    }
                }
                break;
            case '"':
                if (i > 0 && data[i - 1] != '\\') {
                    quoteChar = '\"';
                    inQuotes = !inQuotes; // 判断是否在转义中
                }
                break;
            case ':':
                if (!inQuotes) {
                    if (parentNode->isFlowMap()) {
                        YamlNode &node = (*parentNode)[currentValue];
                        node.initScalar();
                        node.setIsFlow(true);
                        node.setNodeKey(currentValue);
                        node.setKeyQuoteChar(quoteChar);
                        quoteChar = YAML_QuoteCharNone;

                        parentNode = &node;
                        nodeTree.push_back(parentNode);

                        // 结束键，开始值
                        currentValue.clear();
                    }
                }
                break;
            default:
                if (inQuotes) {
                    currentValue += c;
                } else if (!isspace(c)) {
                    currentValue += c;
                }
                break;
            }
            i++;
        }

        if (nodeTree.size() > 0) {
            std::string error = g_errorInvalidFlowScalar + std::string(": ") + data;
            throw std::runtime_error(error);
        }
        return rootNode;
    }

    /// 调试打印，在解析节点数据前，输出已加载的行信息
    void print() {
        auto lastLine = m_Lines.end();
        --lastLine;
        for (auto it = m_Lines.begin(); it != m_Lines.end(); it++) {
            ReaderLine *pLine = *it;
            if (pLine->Type == YamlNode::Sequence) {
                std::cout << "seq ";
            } else if (pLine->Type == YamlNode::Map) {
                std::cout << "map ";
            } else if (pLine->Type == YamlNode::Scalar) {
                std::cout << "sca ";
            } else {
                std::cout << "    ";
            }

            if (pLine->hasFlag(ReaderLine::FoldedScalarFlag)) {
                std::cout << "f";
            } else {
                std::cout << "-";
            }
            if (pLine->hasFlag(ReaderLine::LiteralScalarFlag)) {
                std::cout << "l";
            } else {
                std::cout << "-";
            }
            if (pLine->hasFlag(ReaderLine::ScalarNewlineFlag)) {
                std::cout << "n";
            } else {
                std::cout << "-";
            }
            if (it == lastLine) {
                std::cout << "e";
            } else {
                std::cout << "-";
            }

            std::cout << "| ";
            std::cout << pLine->LineNo << " ";
            if (pLine->Offset > 0 && pLine->Offset != std::string::npos) {
                std::cout << std::string(pLine->Offset, ' ');
            }

            if (pLine->Type == YamlNode::Scalar) {
                std::string scalarValue = pLine->Data;
                for (size_t i = 0; (i = scalarValue.find("\n", i)) != std::string::npos;) {
                    scalarValue.replace(i, 1, "\\n");
                    i += 2;
                }
                std::cout << scalarValue;
                if (pLine->HasComment) {
                    std::cout << " #" << pLine->Comment << std::endl;
                } else {
                    std::cout << std::endl;
                }
            } else if (pLine->Type == YamlNode::Map) {
                std::cout << pLine->Data + ":";
                if (pLine->HasComment) {
                    std::cout << " #" << pLine->Comment << std::endl;
                } else {
                    std::cout << std::endl;
                }
            } else if (pLine->Type == YamlNode::Sequence) {
                std::cout << "-" << std::endl;
            } else if (pLine->Type == YamlNode::EmptyLine) {
                std::cout << "空行/注释行" << std::endl;
            } else {
                std::cout << "> 未知类型 <" << std::endl;
            }
        }
    }

    /// 检查后续尾随的连续空行，并设置行类型为空行
    void postCheckTrailingEmptyLines(std::list<ReaderLine *>::iterator &it) {
        while (it != m_Lines.end()) {
            ReaderLine *pLine = *it;
            if (pLine->Type == YamlNode::None && pLine->Data.size() == 0) {
                pLine->Type = YamlNode::EmptyLine;

                std::list<ReaderLine *>::iterator lastIt = it;
                --lastIt;
                while (lastIt != m_Lines.begin()) {
                    if ((*lastIt)->Type != YamlNode::None && (*lastIt)->Type != YamlNode::Sequence && (*lastIt)->Type != YamlNode::Map) {
                        --lastIt;
                        continue;
                    }
                    pLine->Offset = (*lastIt)->Offset; // 取上一行的偏移
                    break;
                }
                ++it; // 保留原来的空行
            } else {
                break;
            }
        }
    }

private:
    std::list<ReaderLine *> m_Lines;
};

/// 解析YAML文件
void ParseFile(YamlNode &root, const std::string &filePath, bool ignoreEmptyLine, bool printLines) {
    std::ifstream f(filePath, std::ifstream::binary);
    if (f.is_open() == false) {
        throw std::runtime_error(g_errorCannotOpenFile);
    }

    f.seekg(0, f.end);
    size_t fileSize = static_cast<size_t>(f.tellg());
    f.seekg(0, f.beg);

    std::unique_ptr<char[]> data(new char[fileSize]);
    f.read(data.get(), fileSize);
    f.close();

    Parse(root, data.get(), fileSize, ignoreEmptyLine, printLines);
}

/// 解析YAML输入流
void Parse(YamlNode &root, std::iostream &stream, bool ignoreEmptyLine, bool printLines) {
    ParseImp pImp;
    try {
        pImp.Parse(root, stream, ignoreEmptyLine, printLines);
    } catch (const std::runtime_error e) {
        throw;
    }
}

/// 解析YAML字符串
void Parse(YamlNode &root, const std::string &string, bool ignoreEmptyLine, bool printLines) {
    std::stringstream ss(string);
    Parse(root, ss, ignoreEmptyLine, printLines);
}

/// 解析YAML字符串
void Parse(YamlNode &root, const char *buffer, const size_t size, bool ignoreEmptyLine, bool printLines) {
    std::stringstream ss(std::string(buffer, size));
    Parse(root, ss, ignoreEmptyLine, printLines);
}

/// 根据单行最大宽度，自动换行
size_t LineFolding(const std::string &input, std::vector<std::string> &folded, const size_t maxLength) {
    folded.clear();
    if (input.size() == 0) {
        return 0;
    }

    size_t currentPos = 0;
    size_t lastPos = 0;
    size_t spacePos = std::string::npos;
    while (currentPos < input.size()) {
        currentPos = lastPos + maxLength;

        if (currentPos < input.size()) {
            spacePos = input.find_first_of(' ', currentPos);
        }

        if (spacePos == std::string::npos || currentPos >= input.size()) {
            const std::string endLine = input.substr(lastPos);
            if (endLine.size()) {
                folded.push_back(endLine);
            }

            return folded.size();
        }

        folded.push_back(input.substr(lastPos, spacePos - lastPos));

        lastPos = spacePos + 1;
    }

    return folded.size();
}

static void SerializeLoop(YamlNode &node, std::iostream &stream, bool useLevel, const size_t level, const YamlSerializeConfig &config) {
    auto handleNodeComments = [&stream](YamlNode &node, bool emptyLine) {
        if (node.hasComment()) {
            if (!emptyLine) {
                stream << "  ";
            }
            stream << "#" << node.comment() << "\n";
        } else {
            stream << "\n";
        }
    };
    auto handleEmptyLinesAndComments = [&stream, &handleNodeComments](YamlNode &node) {
        if (node.isEmptyLine()) {
            handleNodeComments(node, true);
        }
    };

    auto handleAllEmptyLinesAndComments = [&stream, &handleEmptyLinesAndComments](YamlNode &node) {
        for (auto it = node.begin(); it != node.end(); it++) {
            handleEmptyLinesAndComments((*it).second);
        }
    };

    auto handleStrOutput = [](const std::string &str, char quoteChar, bool isKey) {
        if (quoteChar != YAML_QuoteCharNone) {
            std::string escapeStr = str;
            if (quoteChar == '\"') {
                escapeStr = AddEscapeTokens(escapeStr);
            }
            return quoteChar + escapeStr + quoteChar;
        } else if (ShouldBeCited(str) && (isKey || !IsValidNumeric(str))) {
            std::string escapeStr = str;
            escapeStr = AddEscapeTokens(escapeStr);
            return '\"' + escapeStr + '\"';
        }
        return str;
    };

    const size_t indention = config.SpaceIndentation;

    switch (node.nodeType()) {
    case YamlNode::Sequence: {
        if (node.isFlowSequence()) {
            stream << "[";
            auto begin = node.begin();
            int emptyLineNum = 0;
            int notEmptyLineNo = 0;
            for (auto it = node.begin(); it != node.end(); it++) {
                YamlNode &value = (*it).second;
                if (value.isNone()) {
                    continue;
                }
                if (value.isEmptyLine()) {
                    emptyLineNum++;
                    continue;
                }
                notEmptyLineNo++;
                if (notEmptyLineNo > 1) {
                    stream << ", ";
                }
                if (value.isScalar()) {
                    stream << handleStrOutput(value.asString(), value.valueQuoteChar(), false);
                } else {
                    SerializeLoop(value, stream, true, level + 2, config);
                }
            }
            stream << "]";
            if (node.hasComment()) {
                stream << "  #" << node.comment();
            }
            if (!useLevel) {
                stream << "\n";
                for (auto it = node.begin(); it != node.end(); it++) {
                    YamlNode &value = (*it).second;
                    handleEmptyLinesAndComments(value);
                }
            }
            return;
        }
        for (auto it = node.begin(); it != node.end(); it++) {
            YamlNode &value = (*it).second;
            if (value.isNone()) {
                continue;
            }
            if (value.isEmptyLine()) {
                handleNodeComments(value, true);
                continue;
            }
            stream << std::string(level, ' ') << "- ";
            useLevel = false;
            if (value.isSequence() || (value.isMap() && config.SequenceMapNewline == true)) {
                useLevel = true;
                handleNodeComments(value, false);
            }

            SerializeLoop(value, stream, useLevel, level + 2, config);
        }

    } break;
    case YamlNode::Map: {
        if (node.isFlowMap()) {
            stream << "{";
            int emptyLineNum = 0;
            int notEmptyLineNo = 0;
            for (auto it = node.begin(); it != node.end(); it++) {
                YamlNode &value = (*it).second;
                if (value.isNone()) {
                    continue;
                }
                if (value.isEmptyLine()) {
                    emptyLineNum++;
                    continue;
                }
                notEmptyLineNo++;
                if (notEmptyLineNo > 1) {
                    stream << ", ";
                }
                stream << handleStrOutput(value.nodeKey(), value.keyQuoteChar(), true) << ": ";
                if (value.isScalar()) {
                    stream << handleStrOutput(value.asString(), value.valueQuoteChar(), false);
                } else {
                    SerializeLoop(value, stream, true, level + 2, config);
                }
            }
            stream << "}";
            if (node.hasComment()) {
                stream << "  #" << node.comment();
            }
            if (!useLevel) {
                stream << "\n";
                for (auto it = node.begin(); it != node.end(); it++) {
                    YamlNode &value = (*it).second;
                    handleEmptyLinesAndComments(value);
                }
            }
            return;
        }
        size_t count = 0;
        for (auto it = node.begin(); it != node.end(); it++) {
            YamlNode &value = (*it).second;
            if (value.isNone()) {
                continue;
            }
            if (value.isEmptyLine()) {
                handleNodeComments(value, true);
                continue;
            }

            if (useLevel || count > 0) {
                stream << std::string(level, ' ');
            }

            std::string key = value.nodeKey();
            stream << handleStrOutput(key, value.keyQuoteChar(), true) << ": ";

            useLevel = false;
            if (value.isFlowMap() == false && value.isFlowSequence() == false && (value.isScalar() == false || (value.isScalar() && config.MapScalarNewline))) {
                useLevel = true;
                handleNodeComments(value, false);
            }

            SerializeLoop(value, stream, useLevel, level + indention, config);

            useLevel = true;
            count++;
        }

    } break;
    case YamlNode::Scalar: {
        const std::string value = node.asString();

        std::string trimmedValue = Trim(value);
        if (value.empty()) {
            stream << "\"\"\n";
            handleAllEmptyLinesAndComments(node);
            break;
        }

        bool endNewline = false; // 最后一行是否为空行
        std::vector<std::string> lines;

        const bool literalFlag = static_cast<bool>(node.blockFlags() & ReaderLine::LiteralScalarFlag);
        if (node.isBlockScalar() && literalFlag) {
            std::string line = "";
            std::istringstream iss(value);
            while (iss.eof() == false) {
                std::getline(iss, line);
                lines.push_back(line);
            }

            if (lines.size() > 1) { // 多行排版字符串
                endNewline = lines.back().empty();
                if (endNewline) {
                    lines.pop_back();
                }
            }

            stream << "|";
        } else {
            if (config.ScalarMaxLength == 0 || value.size() <= config.ScalarMaxLength || LineFolding(value, lines, config.ScalarMaxLength) == 1) {
                if (useLevel) {
                    stream << std::string(level, ' ');
                }
                stream << handleStrOutput(value, node.valueQuoteChar(), false);
                handleNodeComments(node, false);
                handleAllEmptyLinesAndComments(node);
                break; // 结束
            } else {
                stream << ">";
            }
        }

        if (endNewline == false) {
            stream << "-"; // 添加-后，内容结尾不会添加空行
        }
        stream << "\n";

        for (auto it = lines.begin(); it != lines.end(); it++) { stream << std::string(level, ' ') << (*it) << "\n"; }

        handleAllEmptyLinesAndComments(node);
    } break;
    case YamlNode::EmptyLine: {
        handleNodeComments(node, false);
    } break;
    default:
        break;
    }
}

YamlSerializeConfig::YamlSerializeConfig(const size_t spaceIndentation, const size_t scalarMaxLength,
                                         const bool sequenceMapNewline, const bool mapScalarNewline) :
    SpaceIndentation(spaceIndentation),
    ScalarMaxLength(scalarMaxLength),
    SequenceMapNewline(sequenceMapNewline),
    MapScalarNewline(mapScalarNewline) {
}

void SerializeToFile(YamlNode &root, const std::string &filePath, const YamlSerializeConfig &config) {
    std::string dirPath = GetDirectoryFromFilePath(filePath);
    bool createFlag = CreateDirectoryx(dirPath);
    if (!createFlag) {
        throw std::runtime_error(g_errorDirectoryCreate);
    }
    std::stringstream stream;
    Serialize(root, stream, config);
    std::ofstream f(filePath);
    if (!f.is_open()) {
        throw std::runtime_error(g_errorCannotOpenFile);
    }
    f.write(stream.str().c_str(), stream.str().size());
    f.close();
}

void Serialize(YamlNode &root, std::iostream &stream, const YamlSerializeConfig &config) {
    if (config.SpaceIndentation < 2) {
        throw std::runtime_error(g_errorIndentation);
    }
    SerializeLoop(root, stream, false, 0, config);
}

void Serialize(YamlNode &root, std::string &string, const YamlSerializeConfig &config) {
    std::stringstream stream;
    Serialize(root, stream, config);
    string = stream.str();
}

std::string ExceptionMessage(const std::string &message, ReaderLine &line) {
    return message + std::string("， Line ") + std::to_string(line.LineNo) + std::string(": ") + line.Data;
}

std::string ExceptionMessage(const std::string &message, ReaderLine &line, const size_t errorPos) {
    return message + std::string("， Line ") + std::to_string(line.LineNo) + std::string(" column ") + std::to_string(errorPos + 1) + std::string(": ") + line.Data;
}

std::string ExceptionMessage(const std::string &message, const size_t errorLine, const size_t errorPos) {
    return message + std::string("， Line ") + std::to_string(errorLine) + std::string(" column ") + std::to_string(errorPos);
}

std::string ExceptionMessage(const std::string &message, const size_t errorLine, const std::string &data) {
    return message + std::string("， Line ") + std::to_string(errorLine) + std::string(": ") + data;
}
}
} // namespace cppc::yaml
